#include <stdio.h>
#include <openssl/x509.h>
#include <openssl/objects.h>
#include <openssl/pem.h>

int main(int argc, char* argv[])
{
    X509 *cert;
    X509_EXTENSION *ext;
    int ext_index;

	// 从文件中加载证书
	FILE *cert_file = fopen("/home/zhahaobing/ca/user.pem", "r");
	cert = PEM_read_X509(cert_file, NULL, NULL, NULL);
	fclose(cert_file);

	// 查找扩展项的索引
	// ext_index = X509_get_ext_by_NID(cert, NID_basic_constraints, -1);
	
	ext_index = X509_get_ext_by_NID(cert, NID_netscape_comment, -1);

	// 检查是否找到扩展项
	if (ext_index != -1) {
		// 获取扩展项
		printf("ext_index=%d, at line %d.\n", ext_index, __LINE__);
		ext = X509_get_ext(cert, ext_index);
//		printf("ext_index=%d, at line %d.\n", ext->critical, __LINE__);

		int critical = X509_EXTENSION_get_critical(ext);
		if (critical) {
			printf("Extension with NID %d is critical\n", ext_index);
		} else {
			printf("Extension with NID %d is not critical,critical=%d\n", ext_index, critical);
		}

		// 删除扩展项
		X509_EXTENSION *ret = X509_delete_ext(cert, ext_index);
		if (NULL != ret) {
			printf("delete NID_basic_constraints success,at line %d.\n", __LINE__);
		}
		if(ext == ret)
		{
			printf("=======,at line %d.\n", __LINE__);
		}
	}

	// 创建一个扩展的数据
	ASN1_OCTET_STRING *extData1 = ASN1_OCTET_STRING_new();
	unsigned char data[] = {0x01, 0x02, 0x03};
	ASN1_STRING_set(extData1, data, sizeof(data));

	// 创建扩展项
    // X509_EXTENSION *ext_new = X509_EXTENSION_create_by_NID(NULL, NID_netscape_comment, 1, (unsigned char *)"true", -1);

	// 创建扩展
	X509_EXTENSION *ext_create = X509_EXTENSION_create_by_NID(&ext, NID_netscape_comment, 0, extData1);

	if (ext_create == NULL) {
        printf("cannot create.\n");
    }
	
	ASN1_OCTET_STRING *ext_createData = X509_EXTENSION_get_data(ext);
	int ext_createDatalen = ext_createData->length;
	printf("len=%d.\n", ext_createDatalen);
	for(int index=0; index < ext_createDatalen; index++)
	{
		if(index%16 == 0)
		{
			printf("\n");
		}
		printf("0x%02x, ", ext_createData->data[index]);
	}
	printf("create succeed.\n");

    /*int ret = PEM_write_X509(output_file, cert);
	printf("ret = %d,at line %d.\n", ret, __LINE__);
    fclose(output_file);*/

    // 释放证书内存
    X509_free(cert);

    return 0;
}

